package ac.svn.accesscontrol.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import ac.notification.event.INotificationListener;
import ac.notification.event.NotificationEvent;
import ac.notification.manager.NotificationRegistrar;
import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.store.Dictionary;
import ac.svn.accesscontrol.store.ISVNIdentifier;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.store.SVNGroup;
import ac.svn.accesscontrol.ui.IUIConstants;
import ac.svn.accesscontrol.ui.UIComponentLibrary;
import ac.svn.accesscontrol.ui.window.MainWindow;
import ac.svn.accesscontrol.utils.Utility;


public class FunctionKeyController implements INotificationListener, ISVNIdentifier
{
	private MainWindow mainWindow;
	public FunctionKeyController(MainWindow mainWindow)
	{
		this.mainWindow = mainWindow;
		addFunctionKeyHandler();
		
		NotificationRegistrar.registerListener(this);
	}
	
	
	private void addFunctionKeyHandler() 
	{
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				saveConfigHandler();
			}
		},
		KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				saveAccessFileHandler(false);
			}
		},
		KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK ),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				saveAccessFileHandler(true);
			}
		},
		KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK |  InputEvent.SHIFT_DOWN_MASK),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				reloadHandler();
			}
		},
		KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);

		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				refreshHandler();
			}
		},
		KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);

		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() 
		{
			@Override
			public void actionPerformed(ActionEvent arg0) 
			{
				mainWindow.setExtendedState(JFrame.MAXIMIZED_BOTH);
			}
		},
		KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
	}

	private void refreshHandler()
	{
		//Send notifications to refresh all lists with latest information in SVN Information Manager.
		Utility.sendNotification(N_UPDATE_LISTINGS,IUIConstants.C_LIST_TYPE_USER);
		Utility.sendNotification(N_UPDATE_LISTINGS,IUIConstants.C_LIST_TYPE_GROUP);
		Utility.sendNotification(N_UPDATE_LISTINGS,IUIConstants.C_LIST_TYPE_LOCATION);
		Utility.sendNotification(N_UPDATE_LISTINGS,IUIConstants.C_LIST_TYPE_ACCESS);
	}
	
	private void reloadHandler()
	{
		Utility.sendNotification(N_GENERAL_PROGRESS_MSG,"Reloading access file!");
		
		//Warn User that the changes made to file might be lost.
		String message = "Changes made might be lost on reload, Do you want to save changes before reloading file?";
		
		int selOption = JOptionPane.showConfirmDialog(mainWindow, message, "Save Changes", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
		if(JOptionPane.YES_OPTION == selOption)
		{
			//Send Commands to save Access and Configuration file.
			Utility.sendNotification(CMD_SAVE_FILE);
			Utility.sendNotification(CMD_SAVE_CONFIG);
		}
		
		//Clear UI Components persisted.
		for(ISVNItem isvnItem : SVNInfoManager.getInfoManager().getAllGroups())
		{
			SVNGroup svnGroup = (SVNGroup) isvnItem;
			for(String userId : svnGroup.getGroupMembers())
			{
				String key = String.format("%s#%s", svnGroup.getGroupAlias(),userId);
				UIComponentLibrary.removeComponent(key);
			}
		}			
		
		//Remove all data from SVN Information Manager. 
		SVNInfoManager.getInfoManager().clearAll();
		
		Utility.sendNotification(CMD_PROCESS_FILE, Dictionary.getDictionary().getLastAccessFile().getAccessFileLocation());
	}

	private void saveAccessFileHandler(boolean saveAs)
	{
		if(saveAs)
		{
			Utility.sendNotification(CMD_SAVE_FILE_AS);
		}
		else
		{
			Utility.sendNotification(CMD_SAVE_FILE);	
		}
		
	}
	
	private void saveConfigHandler()
	{
		//Send Command to merge changes from latest information and then save changes.
		Utility.sendNotification(CMD_MERGE_INFORMATION,Boolean.TRUE);	
	}
	
	@Override
	public Set<String> declaredSubscriptionSet() 
	{
		Set<String> subscriptions = new HashSet<String>();
		subscriptions.add(CMD_RELOAD_FILE);
		return subscriptions;
	}


	@Override
	public void receiveEvent(NotificationEvent notificationEvent) 
	{
		final String neId = notificationEvent.getPropertyIdentifier();
		if(neId.contains(CMD_RELOAD_FILE))
		{
			reloadHandler();
		}
	}

	
	
}
